package com.jic.member.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.orm.Pagination;
import com.jic.common.base.vo.Page;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.common.utils.IDUtils;
import com.jic.member.constant.consist.ResponseCode;
import com.jic.member.constant.enums.*;
import com.jic.member.exception.AppRuntimeException;
import com.jic.member.entity.*;
import com.jic.member.entity.nodevariable.LabelNodeVariable;
import com.jic.member.entity.nodevariable.UserGroupNodeVariable;
import com.jic.member.request.*;
import com.jic.member.response.TripBranchNodeDetailResponse;
import com.jic.member.response.TripEntityResponse;
import com.jic.member.response.TripInfoResponse;
import com.jic.member.mapper.*;
import com.jic.member.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author yinhaijun
 * @date: 2020/6/8
 */
@SuppressWarnings("all")
@Slf4j
@Service("tripService")
public class TripServiceImpl implements TripService {

    @Autowired
    private TripEntityMapper tripEntityMapper;
    @Autowired
    private TripBranchEntityMapper tripBranchEntityMapper;
    @Autowired
    private TripBranchNodeEntityMapper tripBranchNodeEntityMapper;
    @Autowired
    private TripTimingJobEntityMapper tripTimingJobEntityMapper;

    @Autowired
    private TripTimingJobService tripTimingJobService;


    @Autowired
    private TUserGroupService userGroupService;

    @Autowired
    private TripPeopleEntityMapper tripPeopleEntityMapper;
    @Resource
    private TripNodeTemplateEntityMapper tripNodeTemplateEntityMapper;

    @Autowired
    private TripExecuteInfoEntityMapper tripExecuteInfoEntityMapper;

    @Resource
    private TripBranchNodeService tripBranchNodeService;

    public static final Integer DEPT_TYPE_ADMIN = 0;

    public static final Integer DEPT_TYPE_CHILD = 1;

    //旅程查询类型，1：查询基本信息、
    public static final Long ACTICON_TYPE_INFO = 1L;

    //查询旅程，2：查看/编辑
    public static final Long ACTICON_TYPE_OTHER = 2L;

    @Override
    public void saveTest(Long id) {
        // 保存数据
        Date startTime = new Date();
        TripEntity tripEntity = tripEntityMapper.queryById(id);
        // 插入开始节点的定时任务
        tripTimingJobService.register(TripTimingJobTypeEnum.TRIP_START, NodeTemplateTypeEnum.START_NODE.getCode(),3L, startTime, "一个测试开始的旅程", JSON.toJSONString(tripEntity));
    }

    @Override
    public void start(TripEntity tripEntity) {
        log.info("开始圈定用户群体");
        // 查询该旅程下所有分支
        TripBranchEntity tripBranchEntityQ = new TripBranchEntity();
        tripBranchEntityQ.setTripId(tripEntity.getId());
        tripBranchEntityQ.setDeleteFlag(0);
        List<TripBranchEntity> tripBranchEntityList = tripBranchEntityMapper.findAll(tripBranchEntityQ);
        // 查询start节点
        TripBranchNodeEntity startNode = tripBranchNodeEntityMapper.queryStartNodeByTripId(tripEntity.getId());
        for(TripBranchEntity tripBranchEntity : tripBranchEntityList){
            // 查询分支的第一个节点
            TripBranchNodeEntity tripBranchNodeEntityQ = new TripBranchNodeEntity();
            tripBranchNodeEntityQ.setBranchId(tripBranchEntity.getId());
            tripBranchNodeEntityQ.setPrevBranchNodeId(startNode.getId());
            tripBranchNodeEntityQ.setDeleteFlag(0);
            TripBranchNodeEntity firstNode = tripBranchNodeEntityMapper.query(tripBranchNodeEntityQ);
            if(null == firstNode){
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "首节点为空");
            }
            // 圈定用户数据
            delineateUser(startNode, firstNode, tripEntity.getId());

            // 定时触发节点处理
            TripBranchNodeEntity tripBranchNodeEntityQ1 = new TripBranchNodeEntity();
            tripBranchNodeEntityQ1.setBranchId(tripBranchEntity.getId());
            tripBranchNodeEntityQ1.setDeleteFlag(0);
            tripBranchNodeEntityQ1.setNodeTemplateCode(NodeTemplateTypeEnum.TIMED_TRIGGER_NODE.getCode());
            List<TripBranchNodeEntity> timedNodeList = tripBranchNodeEntityMapper.findAll(tripBranchNodeEntityQ1);
            if(null != timedNodeList && !timedNodeList.isEmpty()){
                for(TripBranchNodeEntity tripBranchNode: timedNodeList){
                    // 插入通用定时任务
                    String nodeVariable = tripBranchNode.getNodeVariable();
                    Date executeTime = null;
                    try {
                        JSONObject jsonObject = JSONObject.parseObject(nodeVariable);
                        String executeDateStr = jsonObject.getString("triggerTime");
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        executeTime = format.parse(executeDateStr);
                    } catch (Exception e) {
                        throw new AppRuntimeException(ResponseCode.EXCEPTION, "时间解析异常");
                    }
                    tripTimingJobService.register(TripTimingJobTypeEnum.TIMED_TRIGGER, tripBranchNode.getNodeTemplateCode(), tripBranchNode.getId(), executeTime, "定时触发", tripBranchNode);
                }
            }
            // 事件判断节点处理
            TripBranchNodeEntity tripBranchNodeEntityQ2 = new TripBranchNodeEntity();
            tripBranchNodeEntityQ2.setBranchId(tripBranchEntity.getId());
            tripBranchNodeEntityQ2.setDeleteFlag(0);
            tripBranchNodeEntityQ2.setNodeTemplateCode(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode());
            List<TripBranchNodeEntity> eventJudgeNodeList = tripBranchNodeEntityMapper.findAll(tripBranchNodeEntityQ2);
            if(null != eventJudgeNodeList && !eventJudgeNodeList.isEmpty()) {
                for (TripBranchNodeEntity tripBranchNode : eventJudgeNodeList) {
                    // 插入通用定时任务
                    String nodeVariable = tripBranchNode.getNodeVariable();
                    Date executeTime = null;
                    try {
                        //执行时间需要从JSON里面去解析
                        JSONArray jsonArray = JSONArray.parseArray(nodeVariable);
                        JSONObject jsonbject = (JSONObject) jsonArray.get(0);
                        JSONObject jsonbject1 = (JSONObject) jsonbject.get("eventRangeTime");
                        Long executeTimeLong = (Long) jsonbject1.get("s");
                        executeTime = new Date(executeTimeLong);
                    } catch (Exception e) {
                        throw new AppRuntimeException(ResponseCode.EXCEPTION, "时间解析异常");
                    }
                    tripTimingJobService.register(TripTimingJobTypeEnum.EVENT_CONDITION, tripBranchNode.getNodeTemplateCode(), tripBranchNode.getId(), executeTime, "事件判断-否", tripBranchNode);
                }
            }
        }
        // 更改旅程状态进行中
        tripEntity.setStatus(TripStatusEnum.ON_GOING.getCode());
        log.info("一切准备完毕，旅程正式开始！！");
        tripEntityMapper.update(tripEntity);

        // 旅程结束注册
        if(null != tripEntity.getEndTime()){
            tripTimingJobService.register(TripTimingJobTypeEnum.TRIP_END, NodeTemplateTypeEnum.END_NODE.getCode(), tripEntity.getId(), tripEntity.getEndTime(), "旅程结束", tripEntity);
        }

    }


    @Override
    public RestResult<Long> updateTrip(TripEntityRequest tripEntity) {
        try{
            if (tripEntity.getId() != null && tripEntity.getId() != 0){
                //修改
                tripEntity.setUpdateTime(new Date());
                TripEntity tripEntityVo = new TripEntity();
                BeanUtils.copyProperties(tripEntity,tripEntityVo);
                tripEntityVo.setUpdator(tripEntity.getAdminOperate().getOperator());
                tripEntityVo.setUpdateTime(new Date());
                tripEntityVo.setUpdatorName(tripEntity.getAdminOperate().getOperateName());
                tripEntityMapper.update(tripEntityVo);
                return RestResult.success(tripEntityVo.getId());
            }else{
                TripEntity tripEntityVo = new TripEntity();
                tripEntity.setTripCode(IDUtils.GenerateBillNo("T"));
                tripEntity.setStatus(TripStatusEnum.NO_EDIT_COMPLETE.getCode());
                BeanUtils.copyProperties(tripEntity,tripEntityVo);
                tripEntityVo.setCreator(tripEntity.getAdminOperate().getOperator());
                tripEntityVo.setCreatorName(tripEntity.getAdminOperate().getOperateName());
                tripEntityVo.setDeptType(tripEntity.getAdminOperate().getDeptType().getCode());
                tripEntityVo.setDeptId(tripEntity.getAdminOperate().getDeptId());
                tripEntityVo.setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
                tripEntityVo.setCreateTime(new Date());
                tripEntityMapper.insert(tripEntityVo);
                return RestResult.success(tripEntityVo.getId());
            }
        }catch (Exception e){
            log.error("编辑旅程错误-======>>>>>>>>>>>>{}",e);
            return RestResult.error("9999","编辑旅程错误....");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RestResult<Boolean> confirmSaveOrDraft(TripEntityIdRequest tripEntityIdRequest) {
        try{
            //判断保存为草稿还是确认保存 草稿不校验时间
            Boolean saveType = tripEntityIdRequest.getSaveType();
            if (saveType){
                //校验旅程
                TripEntity tripEntity = tripEntityMapper.queryById(tripEntityIdRequest.getTripId());

                String rest = checkTripBranchNode(tripEntityIdRequest,tripEntity);
                if (StringUtils.isNotEmpty(rest)){
                    return RestResult.error("9999",rest);
                }

                TripEntity tripEntityVo = new TripEntity();
                tripEntityVo.setId(tripEntityIdRequest.getTripId());
                //确认保存 校验旅程时间 修改状态
                if (tripEntity.getTimeType().equals(TripTimeTypeEnums.DYNAMIC_TIME.getCode())){
                    //立即执行
                    tripEntityVo.setStatus(TripStatusEnum.ON_GOING.getCode());
                    //注册开始定时
                    tripTimingJobService.register(TripTimingJobTypeEnum.TRIP_START,NodeTemplateTypeEnum.START_NODE.getCode(),tripEntityVo.getId(),new Date(),"旅程开始定时",tripEntity);
                }else{
                    //判断时间
                    long startTime = tripEntity.getStartTime().getTime();
                    long endTime = tripEntity.getEndTime().getTime();
                    long newTime = System.currentTimeMillis();
                    if(startTime<= newTime){
                        return RestResult.error("9999","旅程开始时间必须大于当前时间");
                    }
                    if(endTime<= newTime){
                        return RestResult.error("9999","旅程结束时间必须大于当前时间");
                    }
                    if(endTime <= startTime){
                        return RestResult.error("9999","旅程结束时间必须大于开始时间");
                    }
                    //判断通过 修改状态为待开始
                    tripEntityVo.setStatus(TripStatusEnum.TO_BE_START.getCode());
                    //注册开始定时
                    tripTimingJobService.register(TripTimingJobTypeEnum.TRIP_START,NodeTemplateTypeEnum.START_NODE.getCode(),tripEntityVo.getId(),tripEntity.getStartTime(),"旅程开始定时",tripEntity);
                }
                tripEntityVo.setLineList(tripEntityIdRequest.getLineList());
                tripEntityMapper.update(tripEntityVo);
            }else{
                //保存草稿
                tripEntityMapper.update(new TripEntity(){{
                    setId(tripEntityIdRequest.getTripId());
                    setStatus(TripStatusEnum.DRAFT.getCode());
                    setLineList(tripEntityIdRequest.getLineList());
                }});
            }
            //最后都要保存 坐标和节点关系
            List<BranchNodeListRequest> nodeList = tripEntityIdRequest.getNodeList();
            nodeList.stream().forEach(node->{
                tripBranchNodeEntityMapper.update(new TripBranchNodeEntity(){{
                   setNodeName(node.getNodeName());
                   setId(node.getNodeId());
                   setTop(node.getTop());
                   setLeft(node.getLeft());
                   setUpdateTime(new Date());
                   setUpdator(tripEntityIdRequest.getAdminOperate().getOperator());
                   setUpdatorName(tripEntityIdRequest.getAdminOperate().getOperateName());
               }});
            });
            return RestResult.success(true);
        }catch (Exception e){
            log.error("确认保存出错.============>>>>>>>>>>{}",e);
            return RestResult.error("9999","保存旅程出错");
        }
    }

    @Override
    public RestResult<TripInfoResponse> getTripDetailAndNodeList(TripEntityIdRequest tripEntityIdRequest) {
        try{
            TripInfoResponse tripInfoResponse = new TripInfoResponse();
            TripEntity tripEntity = tripEntityMapper.queryById(tripEntityIdRequest.getTripId());
            BeanUtils.copyProperties(tripEntity,tripInfoResponse);

            List<Map<String,Object>> restLinkList = new ArrayList<>();
            List<TripBranchNodeDetailResponse> restNodeList = new ArrayList<>();
            //当查询类型为2时 删除top和left为null的
            if (tripEntityIdRequest.getActionType() != null && ACTICON_TYPE_OTHER.equals(tripEntityIdRequest.getActionType())){
                tripBranchNodeService.deleteNodeTopLeftByTripId(tripEntityIdRequest.getTripId());

                List<TripBranchNodeEntity> tripBranchNodeEntityList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
                    setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
                    setTripId(tripEntityIdRequest.getTripId());
                }});
                tripBranchNodeEntityList.stream().forEach(tripBranchNodeEntity -> {
                    TripBranchNodeDetailResponse tripBranchNodeDetailResponse = new TripBranchNodeDetailResponse();
                    BeanUtils.copyProperties(tripBranchNodeEntity,tripBranchNodeDetailResponse);
                    tripBranchNodeDetailResponse.setName(tripBranchNodeEntity.getNodeName());
                    //查询模板
                    TripNodeTemplateEntity tripNodeTemplateEntity = tripNodeTemplateEntityMapper.queryById(tripBranchNodeEntity.getNodeTemplateId());
                    tripBranchNodeDetailResponse.setNextTemplateCodes(tripNodeTemplateEntity != null ? tripNodeTemplateEntity.getNextTemplateCodes() : null);
                    tripBranchNodeDetailResponse.setParentId(tripBranchNodeEntity.getPrevBranchNodeId());
                    tripBranchNodeDetailResponse.setNodeName(tripBranchNodeEntity.getNodeName());
                    tripBranchNodeDetailResponse.setName(tripNodeTemplateEntity.getTemplateName());
                    tripBranchNodeDetailResponse.setNodeId(tripBranchNodeEntity.getId());
                    tripBranchNodeDetailResponse.setIco(tripNodeTemplateEntity.getIco());
                    //设置子级id
                    List<Long> chirldrenId = tripBranchNodeEntityList.stream().filter(node -> tripBranchNodeEntity.getId().equals(node.getPrevBranchNodeId())).map(TripBranchNodeEntity::getId)
                            .collect(Collectors.toList());
                    tripBranchNodeDetailResponse.setChirldrenId(chirldrenId);
                    //如果是事件判断

                    if (tripBranchNodeEntity.getNodeTemplateCode().equals(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode())){
                        //查询下级
                        List<TripBranchNodeEntity> nodeList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
                            setPrevBranchNodeId(tripBranchNodeEntity.getId());
                            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
                        }});
                        if (CollectionUtils.isNotEmpty(nodeList)){
                            List<Map<String,Object>> branchConditionList = new ArrayList<>();
                            nodeList.forEach(node->{
                                branchConditionList.add(new HashMap<String, Object>(){{
                                    put("branchCondition",node.getBranchCondition());
                                }});
                            });
                            tripBranchNodeDetailResponse.setBranchConditionList(branchConditionList == null ? new ArrayList<>() : branchConditionList);
                        }
                    }
                    restNodeList.add(tripBranchNodeDetailResponse);

                    if(!tripBranchNodeEntity.getNodeTemplateCode().equals(NodeTemplateTypeEnum.START_NODE.getCode()) && tripBranchNodeEntity.getPrevBranchNodeId() != null){
                        restLinkList.add(new HashMap<String, Object>(){{
                            put("from",tripBranchNodeEntity.getPrevBranchNodeId());
                            put("to",tripBranchNodeEntity.getId());
                        }});
                    }
                });
            }
            tripInfoResponse.setTripBranchNodeDetailResponseList(restNodeList);
            tripInfoResponse.setLineList(restLinkList);
            return RestResult.success(tripInfoResponse);
        }catch (Exception e){
            log.error("查询旅程信息出错======>>>>>>>>>>>>{}",e);
            return RestResult.error("9999","查询旅程信息错误");
        }
    }

    private void delineateUser(TripBranchNodeEntity startNode, TripBranchNodeEntity node, Long tripId){
        // 查询该标签节点下对应的标签id
        TripLabelArrayRequest request = new TripLabelArrayRequest();
        if(NodeTemplateTypeEnum.LABEL_SELECTION_NODE.getCode().equals(node.getNodeTemplateCode())){
            LabelNodeVariable labelNodeVariable = JSONObject.parseObject(node.getNodeVariable(), LabelNodeVariable.class);
            request.setTripLabelRequestList(labelNodeVariable.getTripLabelRequestList());
        }else if(NodeTemplateTypeEnum.USER_GROUP_SELECTION_NODE.getCode().equals(node.getNodeTemplateCode())) {
            UserGroupNodeVariable userGroupNodeVariable = JSONObject.parseObject(node.getNodeVariable(), UserGroupNodeVariable.class);
            request.setTripUserGroupRequestList(userGroupNodeVariable.getTripUserGroupRequestList());
            request.setRelation(userGroupNodeVariable.getRelation());
        }else if(!NodeTemplateTypeEnum.EVENT_SELECTION_NODE.getCode().equals(node.getNodeTemplateCode())){
            // 第一个节点是不能处理的类型，抛出异常，因为异常会最终存储于通用定时任务
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "圈定用户失败，分支第一个节点是不能处理的类型");
        }else{
            return;
        }
        List<String> thirdUserIds = userGroupService.queryMemberIds(request);
        thirdUserIds.forEach(thirdUserId -> {
            TripExecuteInfoEntity tripExecuteInfoEntity1 = new TripExecuteInfoEntity();
            tripExecuteInfoEntity1.setThirdUserId(thirdUserId);
            tripExecuteInfoEntity1.setBranchId(0L);
            tripExecuteInfoEntity1.setTripId(startNode.getTripId());
            tripExecuteInfoEntity1.setBranchNodeId(startNode.getId());
            tripExecuteInfoEntity1.setNodeTemplateCode(startNode.getNodeTemplateCode());
            tripExecuteInfoEntity1.setRequestVariable(null);
            tripExecuteInfoEntity1.setStatus(1);
            tripExecuteInfoEntity1.setType(2);

            TripExecuteInfoEntity tripExecuteInfoEntity = new TripExecuteInfoEntity();
            tripExecuteInfoEntity.setThirdUserId(thirdUserId);
            tripExecuteInfoEntity.setBranchId(node.getBranchId());
            tripExecuteInfoEntity.setTripId(node.getTripId());
            tripExecuteInfoEntity.setBranchNodeId(node.getId());
            tripExecuteInfoEntity.setNodeTemplateCode(node.getNodeTemplateCode());
            tripExecuteInfoEntity.setRequestVariable(null);
            tripExecuteInfoEntity.setStatus(1);
            tripExecuteInfoEntity.setType(2);

            TripPeopleEntity tripPeopleEntity = new TripPeopleEntity();
            tripPeopleEntity.setThirdUserId(thirdUserId);
            tripPeopleEntity.setBranchId(node.getBranchId());
            tripPeopleEntity.setTripId(tripId);
            tripPeopleEntity.setBranchNodeId(node.getId());
            tripPeopleEntity.setNodeTemplateCode(node.getNodeTemplateCode());
            tripPeopleEntity.setDeleteFlag(0);
            tripPeopleEntity.setCreateTime(new Date());
            tripPeopleEntity.setUpdateTime(tripPeopleEntity.getCreateTime());
            // 如果插入出现异常，不处理，因为可能是中断后再次发起的，预防重复数据，直接在数据库中加入组合唯一索引
            try {
                tripPeopleEntityMapper.insert(tripPeopleEntity);
            }catch (Exception e){
                e.printStackTrace();
            }
            tripExecuteInfoEntityMapper.insert(tripExecuteInfoEntity1);
            tripExecuteInfoEntityMapper.insert(tripExecuteInfoEntity);
        });
    }

    @Override
    public void end(TripEntity tripEntity) {
        log.info("旅程结束");
        // 更改旅程状态结束
        tripEntity.setStatus(TripStatusEnum.END.getCode());
        tripEntity.setUpdateTime(new Date());
        tripEntityMapper.update(tripEntity);
        // 关闭当前旅程未执行完的job
        tripTimingJobService.close(tripEntity.getId());
    }

    /**
     * 查询所有用户旅程
     * @param tripEntity
     * @return
     */
    @Override
    public List<TripEntity> findAll(TripEntity tripEntity) {
        return tripEntityMapper.findAll(tripEntity);
    }

    /**
     * 分页查询用户旅程
     * @param tripEntityQueryRequest
     * @return
     */
    @Override
    public PageResult<TripEntityResponse> queryPage(TripEntityQueryRequest tripEntityQueryRequest) {
        Page pageQuery = new Page();
        pageQuery.setStart(tripEntityQueryRequest.getStart());
        pageQuery.setLimit(tripEntityQueryRequest.getLimit());
        Pagination pagination = Pagination.build(pageQuery.getStart(), pageQuery.getLimit());
//        List<SysDeptResponse> sysDeptResponseList = userSysDeptConsumer.getUserProviderAuthorDept(tripEntityQueryRequest.getAdminOperate().getOperator(),tripEntityQueryRequest.getAdminOperate().getDeptId());
//        if(tripEntityQueryRequest.getAdminOperate().getDeptId().equals(tripEntityQueryRequest.getDeptId())
//            && (DEPT_TYPE_ADMIN.equals(tripEntityQueryRequest.getAdminOperate().getDeptType().getCode())
//            || DEPT_TYPE_CHILD.equals(tripEntityQueryRequest.getAdminOperate().getDeptType().getCode()))){
//            tripEntityQueryRequest.setDeptIds(sysDeptResponseList.stream().map(SysDeptResponse::getId).collect(Collectors.toList()));
//        }
        List<TripEntityResponse> list = tripEntityMapper.queryPage(tripEntityQueryRequest, pagination);
        for(TripEntityResponse entity : list){
//            for(SysDeptResponse sysDeptResponse:sysDeptResponseList){
//                if(entity.getDeptId().equals(sysDeptResponse.getId())){
//                    entity.setDeptName(sysDeptResponse.getDeptName());
//                }
//            }
            entity.setEditFlag(tripEntityQueryRequest.getAdminOperate().getDeptId().equals(entity.getDeptId()) ? true : false);
        }
        int count = tripEntityMapper.queryPageCount(tripEntityQueryRequest);
        PageResult pageResult = new PageResult();
        pageResult.setRows(list);
        pageResult.setTotal(count);
        return pageResult;
    }


    /**
     * 删除用户旅程
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public long delete(Long id) {
        TripEntity tripEntity = new TripEntity();
        tripEntity.setId(id);
        tripEntity.setDeleteFlag(DeleteFlagEnum.DELETE.getCode());
        return tripEntityMapper.update(tripEntity);
    }


    /**
     * 关闭用户旅程
     * @param tripEntity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public long updateStatus(TripEntity tripEntity) {
        //查询分支 分支节点node 删除job
        List<TripBranchEntity> tripBranchEntityList = tripBranchEntityMapper.findAll(new TripBranchEntity(){{setTripId(tripEntity.getId());}});
        List<Long> branchIds = tripBranchEntityList.stream().map(TripBranchEntity::getId).collect(Collectors.toList());
        List<TripBranchNodeEntity> tripBranchNodeEntityList = tripBranchNodeEntityMapper.queryByBranchIds(branchIds);
        List<Long> branchNodeIds = tripBranchNodeEntityList.stream().map(TripBranchNodeEntity::getId).collect(Collectors.toList());
        tripTimingJobEntityMapper.deleteByBranchNodeIds(StringUtils.join(branchNodeIds,","));
        tripEntity.setStatus(TripStatusEnum.CLOSED.getCode());
        tripEntity.setUpdator(tripEntity.getAdminOperate().getOperator());
        tripEntity.setUpdatorName(tripEntity.getAdminOperate().getOperateName());
        return tripEntityMapper.updateStatus(tripEntity);
    }


    /**
     *
     * @param tripEntityIdRequest
     * @return
     */
    public String checkTripBranchNode(TripEntityIdRequest tripEntityIdRequest, TripEntity tripEntity){
        String restString = null;
        //查看是否有开始节点
        TripBranchNodeEntity startNode = tripBranchNodeEntityMapper.query(new TripBranchNodeEntity() {{
            setTripId(tripEntityIdRequest.getTripId());
            setNodeTemplateCode(NodeTemplateTypeEnum.START_NODE.getCode());
            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
        }});
        if(startNode == null){
            restString = "旅程必须要有开始节点";
            return restString;
        }

        List<TripBranchNodeEntity> nodeEntityList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
            setTripId(tripEntityIdRequest.getTripId());
        }});

        if (nodeEntityList.size() < 2 && nodeEntityList.get(0).getNodeTemplateCode().equals(NodeTemplateTypeEnum.START_NODE.getCode())){
            restString  = "节点未创建完成";
            return restString;
        }

        AtomicReference<Boolean> isConnection = new AtomicReference<>(new Boolean(false));

        /**
         * 参数是否填写
         */
        AtomicReference<Boolean> isVariable = new AtomicReference<>(new Boolean(false));

        List<String> checkTimeList = new ArrayList<>();

        for (TripBranchNodeEntity node :nodeEntityList) {
            if(!node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.START_NODE.getCode())){
                if (node.getPrevBranchNodeId() == null || node.getPrevBranchNodeId() == 0L){
                    isConnection.set(true);
                    break;
                }
                //解析 判断节点的开始时间是否大于旅程时间并且结束时间小于旅程结束时间
                if (StringUtils.isEmpty(node.getNodeVariable()) && !node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.END_NODE.getCode())){
                    isVariable.set(true);
                    break;
                }
                //判断定时触发的时间 和事件判断的时间
                try {
                    String checkTimeRest = checkNodeTime(node,tripEntity);
                    if (StringUtils.isNotEmpty(checkTimeRest)){
                        checkTimeList.add(checkTimeRest);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        };
        log.info("节点是否未连接完成====>>>>>>>>>>>>>>>>>>>>{}",isConnection);
        if (isVariable.get()){
            restString = "节点参数未补充完成";
            return restString;
        }
        //节点未连接
        if (isConnection.get()){
            restString = "节点未连接完成";
            return restString;
        }

        //事件判断 时间校验未通过
        if (CollectionUtils.isNotEmpty(checkTimeList)){
            String nodeNameStr = StringUtils.join(checkTimeList, ",");

            if (tripEntity.getTimeType().equals(TripTimeTypeEnums.FIXED_TIME.getCode())){
                restString = "该旅程中"+nodeNameStr+"的时间不能小于旅程开始时间";
            }else{
                restString = "该旅程中"+nodeNameStr+"的时间不能小于当前时间";
            }
            return restString;
        }

        //每个分支是否有结束  true : 没有结束 false 结束
        AtomicReference<Boolean> isEnd = new AtomicReference<>(new Boolean(false));

        AtomicReference<Boolean> isBranch = new AtomicReference<>(new Boolean(false));

        AtomicReference<Boolean> isEndFlag = new AtomicReference<>(false);

        List<TripBranchEntity> branchEntityList = tripBranchEntityMapper.findAll(new TripBranchEntity() {{
            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
            setTripId(tripEntityIdRequest.getTripId());
        }});

        //跳出循环标识
        lxk:


        for (TripBranchEntity branchEntity: branchEntityList) {
            //查询每个分支下是否有结束
            List<TripBranchNodeEntity> tripNodeEndList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
                setNodeTemplateCode(NodeTemplateTypeEnum.END_NODE.getCode());
                setTripId(tripEntityIdRequest.getTripId());
                setBranchId(branchEntity.getId());
                setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
            }});
            if(CollectionUtils.isEmpty(tripNodeEndList)){
                isEnd.set(true);
                break;
            }else{
                //如果存在结束 判断分支下是否有事件判断节点
                List<TripBranchNodeEntity> tripNodeList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
                    setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
                    setNodeTemplateCode(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode());
                    setTripId(tripEntityIdRequest.getTripId());
                    setBranchId(branchEntity.getId());
                }});
                if (CollectionUtils.isNotEmpty(tripNodeList)){
                    //存在事件判断 校验事件判断下是否所有分支都结束了
                    for (TripBranchNodeEntity tripNode:tripNodeList) {
                        //判断当前是否有2个子级
                        List<TripBranchNodeEntity> tripBranchNodeEntityList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
                            setPrevBranchNodeId(tripNode.getId());
                            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
                        }});
                        if (CollectionUtils.isEmpty(tripBranchNodeEntityList) || tripBranchNodeEntityList.size() < 2){
                            isBranch.set(true);
                            break lxk;
                        }
                        List<TripBranchNodeEntity> nodeEntityVoList = tripBranchNodeEntityMapper.queryChildByPrevId(tripNode.getId());
                        //判断下级是否有事件判断
                        List<TripBranchNodeEntity> isJudgment = nodeEntityVoList.stream().filter(node -> node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode()))
                                .collect(Collectors.toList());
                        log.info("判断下级是否有事件判断---------------->>>>>>>>>>>>>>{}",isJudgment);

                        //如果下级没有 判断是否存在两个2结束
                        if (CollectionUtils.isEmpty(isJudgment)){
                            List<TripBranchNodeEntity> isEndList = nodeEntityVoList.stream().filter(node -> node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.END_NODE.getCode()))
                                    .collect(Collectors.toList());
                            log.info("判断是否存在两个2结束---------------->>>>>>>>>>>>>>{}",isEndList);
                            if(CollectionUtils.isEmpty(isEndList) || isEndList.size() < 2){
                                isEndFlag.set(true);
                                break lxk;
                            }
                        }
                    };
                }
            }
        };
        if (isBranch.get()){
            restString = "事件判断必须要有两个分支";
            return restString;
        }
        if(isEnd.get()){
            restString = "本次旅程存在尚未结束的分支，请结束旅程后保存";
            return restString;
        }        //判断事件判断是否都结束
//        Boolean isEndFlag = checkEventJudgment(tripEntityIdRequest.getTripId());
        if (isEndFlag.get()){
            restString = "本次旅程存在尚未结束的分支，请结束旅程后保存";
            return restString;
        }
        return restString;
    }

    /**
     * 判断查询下级是否有分叉
     * @param tripBranchNodeEntity
     * @return
     */
//    public Boolean checkEventJudgment(Long tripId){
//        AtomicReference<Boolean> flag = new AtomicReference<>(false);
//        //查询当前旅程的所有分支
//        List<TripBranchEntity> branchList = tripBranchEntityMapper.findAll(new TripBranchEntity() {{
//            setTripId(tripId);
//            setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
//        }});
//        //查询所有分支下有事件判断的节点
//        branchList.stream().forEach(branch->{
//            List<TripBranchNodeEntity> tripBranchNodeEntityList = tripBranchNodeEntityMapper.findAll(new TripBranchNodeEntity() {{
//                setBranchId(branch.getId());
//                setNodeTemplateCode(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode());
//                setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode());
//            }});
//            //编辑事件判断节点List 查询下级是否存在事件判断
//            tripBranchNodeEntityList.stream().forEach(item->{
//                List<TripBranchNodeEntity> nodeEntityList = tripBranchNodeEntityMapper.queryChildByPrevId(item.getId());
//                //判断下级是否有事件判断
//                List<TripBranchNodeEntity> isJudgment = nodeEntityList.stream().filter(node -> node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode()))
//                        .collect(Collectors.toList());
//                log.info("判断下级是否有事件判断---------------->>>>>>>>>>>>>>{}",isJudgment);
//
//                //如果下级没有 判断是否存在两个2结束
//                if (CollectionUtils.isEmpty(isJudgment)){
//                    List<TripBranchNodeEntity> isEndList = nodeEntityList.stream().filter(node -> node.getNodeTemplateCode().equals(NodeTemplateTypeEnum.END_NODE.getCode()))
//                            .collect(Collectors.toList());
//                    log.info("判断是否存在两个2结束---------------->>>>>>>>>>>>>>{}",isEndList);
//                    if(CollectionUtils.isEmpty(isEndList) || isEndList.size() < 2){
//                        flag.set(true);
//                    }
//                }
//            });
//        });
//        return flag.get();
//    }

    /**
     * 校验节点时间
     * @param tripBranchNodeEntity
     * @return
     */
    public String checkNodeTime(TripBranchNodeEntity tripBranchNodeEntity,TripEntity tripEntity) throws ParseException {
        String rest = "";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if (tripBranchNodeEntity.getNodeTemplateCode().equals(NodeTemplateTypeEnum.TIMED_TRIGGER_NODE.getCode())){
            //定时触发
            if (tripEntity.getTimeType().equals(TripTimeTypeEnums.FIXED_TIME.getCode())){
                //固定时间段
                String nodeVariable = tripBranchNodeEntity.getNodeVariable();
                if (StringUtils.isNotEmpty(nodeVariable)){
                    Map<String,Object> variable = JSONArray.parseObject(nodeVariable, Map.class);
                    String executeDate = variable.get("triggerTime").toString();
                    long exTime = sdf.parse(executeDate).getTime();
                    long newTime = tripEntity.getStartTime().getTime();
                    if (exTime < newTime){
                        rest = variable.get("triggerTime").toString();
                    }
                }
            }else{
                //立即开始
                String nodeVariable = tripBranchNodeEntity.getNodeVariable();
                if (StringUtils.isNotEmpty(nodeVariable)){
                    Map<String,Object> variable = JSONArray.parseObject(nodeVariable, Map.class);
                    String executeDate = variable.get("triggerTime").toString();
                    long exTime = sdf.parse(executeDate).getTime();
                    long newTime = new Date().getTime();
                    if (exTime < newTime){
                        rest = variable.get("triggerTime").toString();
                    }
                }
            }
        }else if(tripBranchNodeEntity.getNodeTemplateCode().equals(NodeTemplateTypeEnum.EVENT_JUDGE_NODE.getCode())){
            //事件判断
            if (tripEntity.getTimeType().equals(TripTimeTypeEnums.FIXED_TIME.getCode())){
                //固定时间段
                String nodeVariable = tripBranchNodeEntity.getNodeVariable();
                if (StringUtils.isNotEmpty(nodeVariable)){
                    List<Map<String,Object>> variable = JSONArray.parseObject(nodeVariable, List.class);
//                    String executeDate = variable.get("executeDate").toString();
                    List<String> restNameList = new ArrayList<>();
                    for (Map<String,Object> vari: variable) {
                        Map<String,Long> eventRangeTime = JSONArray.parseObject(vari.get("eventRangeTime").toString(), Map.class);
                        long exTime = eventRangeTime.get("f");
                        long newTime = tripEntity.getStartTime().getTime();
                        if (exTime < newTime){
                            restNameList.add(vari.get("eventName").toString());
                        }
                    }
                    rest = StringUtils.join(restNameList,",");
                }
            }else{
                //立即开始
                String nodeVariable = tripBranchNodeEntity.getNodeVariable();
                if (StringUtils.isNotEmpty(nodeVariable)){
                    List<Map<String,Object>> variable = JSONArray.parseObject(nodeVariable, List.class);
//                    String executeDate = variable.get("executeDate").toString();
                    List<String> restNameList = new ArrayList<>();
                    for (Map<String,Object> vari: variable) {
                        Map<String,Long> eventRangeTime = JSONArray.parseObject(vari.get("eventRangeTime").toString(), Map.class);
                        long exTime = eventRangeTime.get("f");
                        long newTime = new Date().getTime();
                        if (exTime < newTime){
                            restNameList.add(vari.get("eventName").toString());
                        }
                    }
                    rest = StringUtils.join(restNameList,",");
                }
            }
        }
        return rest;
    }


}
